package com.kk.nio.work01.server.channeldata;

import java.nio.channels.SocketChannel;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;

import com.kk.nio.work01.server.channeldata.impl.DefChannelDataServiceImpl;
import com.kk.nio.work01.server.pool.FixedThreadPool;
import com.kk.nio.work01.server.pool.ThreadPool;

/**
 * 进行读取线程的数据处理
* 源文件名：ReadChannelProcess.java
* 文件版本：1.0.0
* 创建作者：liujun
* 创建日期：2016年11月4日
* 修改作者：liujun
* 修改日期：2016年11月4日
* 文件描述：liujun
* 版权所有：Copyright 2016 zjhz, Inc. All Rights Reserved.
*/
public class ChannelDataProcess implements Runnable {

    /**
     * 用来存放读取通道的队列信息
    * @字段说明 readQueue
    */
    private BlockingQueue<SocketChannel> readQueue = new LinkedBlockingQueue<SocketChannel>(100);

    /**
     * 当前正在使用的通道信息
    * @字段说明 userChannel
    */
    private ConcurrentHashMap<Integer, SocketChannel> useChannelMap = new ConcurrentHashMap<>();
    /**
     * 读取通道操作
    * @字段说明 INSTANCE
    */
    private static final ChannelDataProcess INSTANCE = new ChannelDataProcess();

    /**
     * 运行标识，true，正在运行,false停止
    * @字段说明 runFlag
    */
    private volatile boolean runFlag = true;

    /**
     * 进行读取的流程,使用默认的流程
    * @字段说明 READLIST
    */
    private ChannelDataServiceInf readService = new DefChannelDataServiceImpl();

    /**
     * 线程池对象
    * @字段说明 readChannelProc
    */
    private ThreadPool<Runnable> threadPool = new FixedThreadPool<Runnable>();

    /**
     * 获取实例对象信息
    * 方法描述
    * @return
    * @创建日期 2016年11月4日
    */
    public static ChannelDataProcess getInstance() {
        return INSTANCE;
    }

    public ChannelDataProcess() {

    }

    public void setReadService(ChannelDataServiceInf readService) {
        this.readService = readService;
    }

    // 添加通道信息
    public void addReadChannel(int id, SocketChannel channel) {

        // 仅当不包含的时候，才进行添加到通道队列中
        if (!useChannelMap.containsKey(id)) {
            if (useChannelMap.putIfAbsent(id, channel) == null) {
                this.readQueue.add(channel);
                // 提交当前的任务
                threadPool.execute(this);
            }
        }
    }

    @Override
    public void run() {
        while (runFlag) {
            try {
                SocketChannel channel = readQueue.take();
                // 进行数据数据操作
                readService.dataProcess(channel);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public void shutdown() {
        this.runFlag = false;
    }

}
